#!/bin/bash

# 将QEMU虚拟机导入到virt-manager的脚本
# 用于将手动创建的QEMU虚拟机导入到libvirt管理

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 加载配置文件
load_config() {
    local config_file="$(dirname "$0")/config.conf"
    if [[ -f "$config_file" ]]; then
        source "$config_file"
        log_info "已加载配置文件: $config_file"
    else
        log_error "配置文件不存在: $config_file"
        exit 1
    fi
}

# 检查libvirt服务
check_libvirt() {
    log_info "检查libvirt服务状态..."
    
    if ! systemctl is-active --quiet libvirtd; then
        log_warning "libvirtd服务未运行，正在启动..."
        sudo systemctl start libvirtd
        sudo systemctl enable libvirtd
    fi
    
    # 检查用户是否在libvirt组中
    if ! groups $USER | grep -q libvirt; then
        log_warning "用户 $USER 不在libvirt组中"
        log_info "请运行: sudo usermod -aG libvirt $USER"
        log_info "然后重新登录或执行: newgrp libvirt"
        exit 1
    fi
    
    log_success "libvirt服务检查完成"
}

# 生成libvirt XML配置
generate_libvirt_xml() {
    local vm_name="$1"
    local vm_info_file="$2"
    local xml_file="$3"
    
    # 安全读取虚拟机信息，过滤掉注释和时间戳
    while IFS='=' read -r key value; do
        # 跳过注释行和空行
        [[ "$key" =~ ^#.*$ ]] && continue
        [[ -z "$key" ]] && continue
        # 跳过时间戳行
        [[ "$key" == "CREATED_TIME" ]] && continue
        # 导出变量
        export "$key"="$value"
    done < "$vm_info_file"
    
    log_info "为虚拟机 $vm_name 生成libvirt XML配置..."
    
    cat > "$xml_file" << EOF
<domain type='kvm'>
  <name>$vm_name</name>
  <uuid>$(uuidgen)</uuid>
  <memory unit='KiB'>$(($VM_MEMORY * 1024))</memory>
  <currentMemory unit='KiB'>$(($VM_MEMORY * 1024))</currentMemory>
  <vcpu placement='static'>$VM_VCPUS</vcpu>
  <os>
    <type arch='x86_64' machine='pc-i440fx-2.12'>hvm</type>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
  </features>
  <cpu mode='host-model' check='partial'/>
  <clock offset='utc'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <pm>
    <suspend-to-mem enabled='no'/>
    <suspend-to-disk enabled='no'/>
  </pm>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='$VM_DISK'/>
      <target dev='vda' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
    </disk>
    <controller type='usb' index='0' model='ich9-ehci1'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x7'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci1'>
      <master startport='0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0' multifunction='on'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci2'>
      <master startport='2'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x1'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci3'>
      <master startport='4'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x2'/>
    </controller>
    <controller type='pci' index='0' model='pci-root'/>
    <controller type='ide' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
    </controller>
    <controller type='virtio-serial' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
    </controller>
    <interface type='bridge'>
      <mac address='$VM_MAC'/>
      <source bridge='$BRIDGE_NAME'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    <serial type='pty'>
      <target type='isa-serial' port='0'>
        <model name='isa-serial'/>
      </target>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <channel type='unix'>
      <target type='virtio' name='org.qemu.guest_agent.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    </channel>
    <input type='tablet' bus='usb'>
      <address type='usb' bus='0' port='1'/>
    </input>
    <input type='mouse' bus='ps2'/>
    <input type='keyboard' bus='ps2'/>
    <graphics type='vnc' port='$VNC_PORT' autoport='no' listen='0.0.0.0'>
      <listen type='address' address='0.0.0.0'/>
    </graphics>
    <sound model='ich6'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </sound>
    <video>
      <model type='cirrus' vram='16384' heads='1' primary='yes'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
    <redirdev bus='usb' type='spicevmc'>
      <address type='usb' bus='0' port='2'/>
    </redirdev>
    <redirdev bus='usb' type='spicevmc'>
      <address type='usb' bus='0' port='3'/>
    </redirdev>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
    </memballoon>
  </devices>
</domain>
EOF
    
    log_success "XML配置文件已生成: $xml_file"
}

# 导入虚拟机到libvirt
import_vm_to_libvirt() {
    local vm_name="$1"
    local xml_file="$2"
    
    log_info "导入虚拟机 $vm_name 到libvirt..."
    
    # 检查虚拟机是否已存在
    if virsh list --all | grep -q "$vm_name"; then
        log_warning "虚拟机 $vm_name 已存在于libvirt中"
        read -p "是否覆盖现有配置? (y/N): " -n 1 -r
        echo
        if [[ $REPLY =~ ^[Yy]$ ]]; then
            virsh undefine "$vm_name" 2>/dev/null || true
        else
            log_info "跳过虚拟机 $vm_name"
            return 0
        fi
    fi
    
    # 定义虚拟机
    if virsh define "$xml_file"; then
        log_success "虚拟机 $vm_name 已成功导入到libvirt"
        
        # 设置为自动启动（可选）
        read -p "是否设置虚拟机 $vm_name 为自动启动? (y/N): " -n 1 -r
        echo
        if [[ $REPLY =~ ^[Yy]$ ]]; then
            virsh autostart "$vm_name"
            log_success "虚拟机 $vm_name 已设置为自动启动"
        fi
    else
        log_error "导入虚拟机 $vm_name 失败"
        return 1
    fi
}

# 导入单个虚拟机
import_single_vm() {
    local vm_name="$1"
    
    if [[ -z "$vm_name" ]]; then
        log_error "请指定虚拟机名称"
        return 1
    fi
    
    # 从配置文件读取虚拟机存储路径
    local vm_info_file="$VM_IMAGE_DIR/$vm_name.info"
    local xml_file="/tmp/$vm_name.xml"
    
    # 检查虚拟机信息文件
    if [[ ! -f "$vm_info_file" ]]; then
        log_error "虚拟机信息文件不存在: $vm_info_file"
        return 1
    fi
    
    # 生成XML配置并导入
    generate_libvirt_xml "$vm_name" "$vm_info_file" "$xml_file"
    import_vm_to_libvirt "$vm_name" "$xml_file"
}

# 导入所有虚拟机
import_all_vms() {
    log_info "导入所有虚拟机到libvirt..."
    
    if [[ ! -d "$VM_IMAGE_DIR" ]]; then
        log_error "虚拟机存储目录不存在: $VM_IMAGE_DIR"
        return 1
    fi
    
    local vm_count=0
    local success_count=0
    
    for info_file in "$VM_IMAGE_DIR"/*.info; do
        if [[ -f "$info_file" ]]; then
            local vm_name=$(basename "$info_file" .info)
            log_info "处理虚拟机: $vm_name"
            
            ((vm_count++))
            if import_single_vm "$vm_name"; then
                ((success_count++))
            fi
            echo
        fi
    done
    
    log_info "导入完成: $success_count/$vm_count 个虚拟机成功导入"
}

# 显示libvirt中的虚拟机列表
show_libvirt_vms() {
    log_info "libvirt中的虚拟机列表:"
    echo
    virsh list --all
    echo
    
    log_info "可以使用以下命令管理虚拟机:"
    echo "  virsh start <vm_name>     # 启动虚拟机"
    echo "  virsh shutdown <vm_name>  # 关闭虚拟机"
    echo "  virsh reboot <vm_name>    # 重启虚拟机"
    echo "  virsh console <vm_name>   # 连接控制台"
    echo "  virt-manager              # 打开图形管理界面"
}

# 启动virt-manager
start_virt_manager() {
    log_info "启动virt-manager图形界面..."
    
    if command -v virt-manager >/dev/null 2>&1; then
        virt-manager &
        log_success "virt-manager已启动"
    else
        log_error "virt-manager未安装"
        log_info "请安装: sudo apt install virt-manager  # Ubuntu"
        log_info "或: sudo yum install virt-manager      # CentOS"
    fi
}

# 显示帮助信息
show_help() {
    echo "QEMU虚拟机导入到virt-manager脚本"
    echo
    echo "使用方法:"
    echo "  $0 <命令> [参数]"
    echo
    echo "命令:"
    echo "  import <vm_name>  导入指定的虚拟机"
    echo "  import-all        导入所有虚拟机"
    echo "  list              显示libvirt中的虚拟机列表"
    echo "  gui               启动virt-manager图形界面"
    echo "  help              显示此帮助信息"
    echo
    echo "示例:"
    echo "  $0 import k8s-master1     # 导入master1虚拟机"
    echo "  $0 import-all             # 导入所有虚拟机"
    echo "  $0 list                   # 查看虚拟机列表"
    echo "  $0 gui                    # 启动图形界面"
    echo
    echo "注意:"
    echo "  - 确保libvirtd服务正在运行"
    echo "  - 确保用户在libvirt组中"
    echo "  - 虚拟机必须先通过create-vm.sh创建"
}

# 主函数
main() {
    local command="${1:-}"
    local vm_name="${2:-}"
    
    case "$command" in
        "import")
            if [[ -z "$vm_name" ]]; then
                log_error "请指定虚拟机名称"
                echo "使用方法: $0 import <vm_name>"
                exit 1
            fi
            load_config
            check_libvirt
            import_single_vm "$vm_name"
            ;;
        "import-all")
            load_config
            check_libvirt
            import_all_vms
            ;;
        "list")
            check_libvirt
            show_libvirt_vms
            ;;
        "gui")
            check_libvirt
            start_virt_manager
            ;;
        "help"|"--help"|"-h")
            show_help
            ;;
        "")
            log_error "请指定命令"
            show_help
            exit 1
            ;;
        *)
            log_error "未知命令: $command"
            show_help
            exit 1
            ;;
    esac
}

# 执行主函数
main "$@"